package com.dome.base.interceptor;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.dome.auth.UserContextHolder;
import com.dome.auth.utils.UserUtil;
import com.dome.client.config.exception.ServerException;
import com.dome.client.config.result.enums.RtnResultCodeEnums;
import com.dome.user.entity.dto.UserLoginDTO;
import com.dome.util.constans.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户信息拦截器(记录日志MDC)
 * @author jinjie.chen
 */
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
    public static final String KEY_USER = "user";
    //白名单签名值 方便测试用
    private String signingKey = "123456";
    //白名单url
    private static List<String> ignoreUrls=null;
    static {
        ignoreUrls=new ArrayList<>();
        ignoreUrls.add("/user/login");
    }
    public UserInterceptor() {

    }
    public UserInterceptor(String signingKey) {
        if(StringUtils.isNotEmpty(signingKey)) {
            this.signingKey = signingKey;
        }
    }
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri= request.getRequestURI();
        if(ignoreUrls.contains(uri)){
            return true;
        }
        //从网关获取并校验,通过校验就可信任x-client-token-user中的信息
        try {

            String token = request.getHeader(CommonConstants.X_CLIENT_TOKEN);
            String version = request.getHeader(CommonConstants.CONTEXT_KEY_VERSION);
            //String traceId = request.getHeader(CommonConstants.LOG_KEY_TRADE_ID);
            if(version!=null) {
                UserContextHolder.getInstance().setVersion(version);
            }

            String account = "";
            //UserContextHolder.getInstance().setTraceId(traceId);
            //MDC.put(CommonConstants.LOG_KEY_TRADE_ID,traceId);
            if(StringUtils.isNotBlank(token)){
                if(signingKey.equals(token)) {
                    //如果是白名单连接往下传.token将是密钥signingKey
                    return true;
                }

                UserContextHolder.getInstance().setToken(token);
                //account = JwtUtils.getAccount(token);
               // MDC.put(KEY_USER,account);
            }
            //token全局检验
            UserLoginDTO userLoginEntity = UserUtil.getPrincipal();
            if(userLoginEntity == null) {
                log.error("uri:{} token查询不到数值.登陆超时accountKey:{}",uri, UserContextHolder.getInstance().getLoginRedisKey());
                throw new ServerException(RtnResultCodeEnums.NOTLOGIN);
            } else {
                UserContextHolder.getInstance().set(UserUtil.KEY_USERLOGINENTITY,userLoginEntity);
            }
        } catch (JWTDecodeException e) {
            log.error("jwt异常",e.getMessage());
        }
        return true;
    }

    private void checkToken(String token) {
        //TODO 从网关获取并校验,通过校验就可信任x-client-token-user中的信息
        log.debug("//TODO 校验token:{}", token);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
        //MDC.remove(KEY_USER);
        UserContextHolder.getInstance().clear();
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
    }
}
